﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Physis.Core.Sponsor {

    public class SponsorEnrollment : CoreDateSegmentObject { 
        
        #region Private Properties

        private Int64 sponsorId = 0;

        private Int64 parentSponsorId = 0;

        private Int64 programId = 0;


        private Int64 enrollmentActionReasonId = 0;

        private Int64 terminationActionReasonId = 0;

        private Int64 voidedActionReasonId = 0;


        private Sponsor sponsor = null;

        private Sponsor parentSponsor = null;

        private Insurer.Program program = null;

        private General.ActionReason enrollmentActionReason = null;

        private General.ActionReason terminationActionReason = null;

        private General.ActionReason voidedActionReason = null;

        #endregion 


        #region Public Properties

        public Int64 SponsorId { get { return sponsorId; } }

        public Sponsor Sponsor {

            get {

                if (sponsor == null) { sponsor = Application.Core.Sponsor.Sponsor (sponsorId, true); }

                return sponsor;

            }

        }

        public String SponsorName { get { return ((Sponsor != null) ? Sponsor.Name : String.Empty); } }


        public Int64 ParentSponsorId { get { return parentSponsorId; } }

        public Sponsor ParentSponsor {

            get {

                if (parentSponsor == null) { parentSponsor = Application.Core.Sponsor.Sponsor (parentSponsorId, true); }

                return parentSponsor;

            }

        }

        public String ParentSponsorName { get { return ((ParentSponsor != null) ? ParentSponsor.Name : String.Empty); } }


        public Int64 ProgramId { get { return programId; } }

        public Insurer.Program Program {

            get {

                if (program == null) { program = Application.Core.Insurer.Program (programId, true); }

                return program;

            }

        }

        public String ProgramName { get { return ((Program != null) ? Program.Name : String.Empty); } }



        public Int64 EnrollmentActionReasonId { get { return enrollmentActionReasonId; } }

        public General.ActionReason EnrollmentActionReason {

            get {

                if (enrollmentActionReason == null) { enrollmentActionReason = Application.Core.General.ActionReason (enrollmentActionReasonId, true); }

                return enrollmentActionReason;

            }

        }

        public Int64 TerminationActionReasonId { get { return terminationActionReasonId; } }

        public General.ActionReason TerminationActionReason {

            get {

                if (terminationActionReason == null) { terminationActionReason = Application.Core.General.ActionReason (terminationActionReasonId, true); }

                return terminationActionReason;

            }

        }

        public Int64 VoidedActionReasonId { get { return voidedActionReasonId; } }

        public General.ActionReason VoidedActionReason {

            get {

                if (voidedActionReason == null) { voidedActionReason = Application.Core.General.ActionReason (voidedActionReasonId, true); }

                return voidedActionReason;

            }

        }

        #endregion 

        
        #region Constructors

        public SponsorEnrollment (Application forApplication) : base (forApplication) {

            return;

        }

        public SponsorEnrollment (Application forApplication, Int64 forId) : base (forApplication, forId) {

            return;

        }

        public SponsorEnrollment (Application forApplication, Int64 forSponsorId, DateTime forEffectiveDate, Int64 forEnrollmentActionReasonId, Int64 forParentSponsorId, Int64 forProgramId) : base (forApplication)  {

            sponsorId = forSponsorId;

            EffectiveDate = forEffectiveDate;

            enrollmentActionReasonId = forEnrollmentActionReasonId;

            if (forParentSponsorId == 0) {

                // IF DIRECT ENROLLMENT, LEAVE THE SEGMENT OPEN

                TerminationDate = DateTime.MaxValue;

                programId = forProgramId;

            }

            else {

                // IF ENROLLED THROUGH ANOTHER GROUP, THE TERMINATION DATE 

                // MUST BE LESS THAN THE OTHER GROUP'S SEGMENT TERMINATION DATE 

                // VALIDATE THE PROGRAM IS AVAILABLE, TOO

                parentSponsorId = forParentSponsorId;


                // TODO: IMPLEMENT THIS LOGIC, FOR NOW JUST SET TO OPEN 

                TerminationDate = DateTime.MaxValue;

                programId = forProgramId;

            }

            return;

        }

        #endregion


        #region Database Functions

        protected override Dictionary<String, String> Validate () {

            Dictionary<String, String> validationErrors = new Dictionary<string, string> (); // DO NOT USE BASE VALIDATORS

            if (Id == 0) {



            }

            else {

            }


            return validationErrors;

        }

        public override void MapDataFields (System.Data.DataRow currentRow) {
            
            base.MapDataFields (currentRow);


            sponsorId = Data.Readers.DataReader.Int64FromDatabase (currentRow, "SponsorId");

            parentSponsorId = Data.Readers.DataReader.Int64FromDatabase (currentRow, "ParentSponsorId");

            programId = Data.Readers.DataReader.Int64FromDatabase (currentRow, "ProgramId");


            enrollmentActionReasonId = Data.Readers.DataReader.Int64FromDatabase (currentRow, "EnrollmentActionReasonId");

            terminationActionReasonId = Data.Readers.DataReader.Int64FromDatabase (currentRow, "TerminationActionReasonId");

            voidedActionReasonId = Data.Readers.DataReader.Int64FromDatabase (currentRow, "VoidedActionReasonId");

            return;

        }

        public override Boolean Save () {

            Boolean success = false;

            try {

                Dictionary<String, String> validationErrors = Validate ();

                if (validationErrors.Count > 0) {

                    Application.SetLastException (new Exception ("Invalid [" + validationErrors.Keys.First () + "]: " + validationErrors.Values.First ()));

                    return false;

                }

                UpdateModifiedToSessionUser ();


                Application.EnvironmentDatabase.BeginTransaction ();

                System.Data.IDbCommand command;

                if (Id == 0) {

                    command = Application.EnvironmentDatabase.CreateCommand ("SponsorEnrollment_Insert");

                    command.CommandType = System.Data.CommandType.StoredProcedure;


                    Application.EnvironmentDatabase.AppendCommandParameter (command, "SponsorId", SponsorId);

                    Application.EnvironmentDatabase.AppendCommandParameter (command, "ParentSponsorId", (Int64?) ((ParentSponsorId == 0) ? (Int64?) null : ParentSponsorId));

                    Application.EnvironmentDatabase.AppendCommandParameter (command, "ProgramId", ProgramId);

                    Application.EnvironmentDatabase.AppendCommandParameter (command, "EffectiveDate", EffectiveDate);

                    Application.EnvironmentDatabase.AppendCommandParameter (command, "TerminationDate", TerminationDate);

                    Application.EnvironmentDatabase.AppendCommandParameter (command, "EnrollmentActionReasonId", EnrollmentActionReasonId);

                    Application.EnvironmentDatabase.AppendCommandParameter (command, "ModifiedId", Application.Session.UserAccountName, 60);

                    success = (command.ExecuteNonQuery () > 0);

                    if (success) { SetIdentity (); }

                    else if (Application.EnvironmentDatabase.LastException == null) { throw new Exception ("Unable to save new Sponsor Enrolllment."); }

                    else { throw Application.EnvironmentDatabase.LastException; }

                }

                Application.EnvironmentDatabase.CommitTransaction ();

            }

            catch (Exception exception) {

                success = false;

                Application.SetLastException (exception);

                Application.EnvironmentDatabase.RollbackTransaction ();

            }

            return success;

        }

        #endregion 


    }

}
